"use client"

import React, { useRef, useState, useEffect } from "react"
import { cn } from "@/lib/utils"

type Tool = "pencil" | "eraser" | "fill" | "text" | "select" | "shape"
type ShapeType = "rectangle" | "circle" | "line" | "none"

interface CanvasProps {
  activeTool: Tool
  activeColor: string
  brushSize: number
  activeShape: ShapeType
  className?: string
  canvasRef?: React.RefObject<HTMLCanvasElement>
}

export function Canvas({
  activeTool,
  activeColor,
  brushSize,
  activeShape,
  className,
  canvasRef: externalCanvasRef,
}: CanvasProps) {
  const internalCanvasRef = useRef<HTMLCanvasElement>(null)
  const canvasRef = externalCanvasRef || internalCanvasRef
  const [isDrawing, setIsDrawing] = useState(false)
  const [lastPosition, setLastPosition] = useState({ x: 0, y: 0 })
  const [shapeStart, setShapeStart] = useState({ x: 0, y: 0 })
  const [canvasHistory, setCanvasHistory] = useState<ImageData[]>([])
  const [historyIndex, setHistoryIndex] = useState(-1)
  
  // Text tool states
  const [isTextInputActive, setIsTextInputActive] = useState(false)
  const [textInputPosition, setTextInputPosition] = useState({ x: 0, y: 0 })
  const [textInputValue, setTextInputValue] = useState("")
  const textInputRef = useRef<HTMLInputElement>(null)
  
  // Initialize canvas
  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    // Set canvas size to match its display size
    canvas.width = canvas.offsetWidth
    canvas.height = canvas.offsetHeight
    
    // Fill with white background
    ctx.fillStyle = "#ffffff"
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    
    // Save initial state to history
    const initialState = ctx.getImageData(0, 0, canvas.width, canvas.height)
    setCanvasHistory([initialState])
    setHistoryIndex(0)
  }, [])
  
  // Handle window resize
  useEffect(() => {
    const handleResize = () => {
      const canvas = canvasRef.current
      if (!canvas) return
      
      const ctx = canvas.getContext("2d")
      if (!ctx) return
      
      // Save current image
      const currentImage = ctx.getImageData(0, 0, canvas.width, canvas.height)
      
      // Resize canvas
      canvas.width = canvas.offsetWidth
      canvas.height = canvas.offsetHeight
      
      // Restore image
      ctx.putImageData(currentImage, 0, 0)
    }
    
    window.addEventListener("resize", handleResize)
    return () => window.removeEventListener("resize", handleResize)
  }, [])
  
  // Save state to history
  const saveToHistory = () => {
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    const currentState = ctx.getImageData(0, 0, canvas.width, canvas.height)
    
    // Remove any states after current index (if we've undone and then drawn something new)
    const newHistory = canvasHistory.slice(0, historyIndex + 1)
    
    setCanvasHistory([...newHistory, currentState])
    setHistoryIndex(newHistory.length)
  }
  
  // Undo function
  const undo = () => {
    if (historyIndex > 0) {
      const canvas = canvasRef.current
      if (!canvas) return
      
      const ctx = canvas.getContext("2d")
      if (!ctx) return
      
      const newIndex = historyIndex - 1
      ctx.putImageData(canvasHistory[newIndex], 0, 0)
      setHistoryIndex(newIndex)
    }
  }
  
  // Redo function
  const redo = () => {
    if (historyIndex < canvasHistory.length - 1) {
      const canvas = canvasRef.current
      if (!canvas) return
      
      const ctx = canvas.getContext("2d")
      if (!ctx) return
      
      const newIndex = historyIndex + 1
      ctx.putImageData(canvasHistory[newIndex], 0, 0)
      setHistoryIndex(newIndex)
    }
  }
  
  // Handle keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Ctrl+Z for undo
      if (e.ctrlKey && e.key === "z") {
        e.preventDefault()
        undo()
      }
      
      // Ctrl+Y for redo
      if (e.ctrlKey && e.key === "y") {
        e.preventDefault()
        redo()
      }
    }
    
    window.addEventListener("keydown", handleKeyDown)
    return () => window.removeEventListener("keydown", handleKeyDown)
  }, [historyIndex, canvasHistory])
  
  // Drawing functions
  const startDrawing = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    const rect = canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    if (activeTool === "text") {
      // Handle text tool click
      setTextInputPosition({ x, y })
      setTextInputValue("")
      setIsTextInputActive(true)
      // Focus the text input after it's rendered
      setTimeout(() => {
        if (textInputRef.current) {
          textInputRef.current.focus()
        }
      }, 10)
      return
    }
    
    setIsDrawing(true)
    setLastPosition({ x, y })
    
    if (activeTool === "shape") {
      setShapeStart({ x, y })
    } else if (activeTool === "pencil" || activeTool === "eraser") {
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineTo(x, y)
      ctx.stroke()
    }
  }
  
  // Handle text input completion
  const handleTextInputComplete = () => {
    if (!textInputValue.trim()) {
      setIsTextInputActive(false)
      return
    }
    
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    // Set text properties
    ctx.font = `${brushSize * 2}px Arial`
    ctx.fillStyle = activeColor
    ctx.textBaseline = "top"
    
    // Draw text on canvas
    ctx.fillText(textInputValue, textInputPosition.x, textInputPosition.y)
    
    // Reset text input state
    setIsTextInputActive(false)
    setTextInputValue("")
    
    // Save to history
    saveToHistory()
  }
  
  const draw = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (!isDrawing) return
    
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    const rect = canvas.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top
    
    if (activeTool === "pencil") {
      ctx.strokeStyle = activeColor
      ctx.lineWidth = brushSize
      ctx.lineCap = "round"
      ctx.lineJoin = "round"
      
      ctx.beginPath()
      ctx.moveTo(lastPosition.x, lastPosition.y)
      ctx.lineTo(x, y)
      ctx.stroke()
    } else if (activeTool === "eraser") {
      ctx.strokeStyle = "#ffffff" // White for eraser
      ctx.lineWidth = brushSize
      ctx.lineCap = "round"
      ctx.lineJoin = "round"
      
      ctx.beginPath()
      ctx.moveTo(lastPosition.x, lastPosition.y)
      ctx.lineTo(x, y)
      ctx.stroke()
    }
    
    setLastPosition({ x, y })
  }
  
  const stopDrawing = () => {
    if (!isDrawing) return
    
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    if (activeTool === "shape" && activeShape !== "none") {
      drawShape(ctx, shapeStart, lastPosition)
    }
    
    setIsDrawing(false)
    saveToHistory()
  }
  
  const drawShape = (
    ctx: CanvasRenderingContext2D,
    start: { x: number; y: number },
    end: { x: number; y: number }
  ) => {
    ctx.strokeStyle = activeColor
    ctx.lineWidth = brushSize
    
    if (activeShape === "rectangle") {
      const width = end.x - start.x
      const height = end.y - start.y
      ctx.strokeRect(start.x, start.y, width, height)
    } else if (activeShape === "circle") {
      const radius = Math.sqrt(
        Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2)
      )
      ctx.beginPath()
      ctx.arc(start.x, start.y, radius, 0, 2 * Math.PI)
      ctx.stroke()
    } else if (activeShape === "line") {
      ctx.beginPath()
      ctx.moveTo(start.x, start.y)
      ctx.lineTo(end.x, end.y)
      ctx.stroke()
    }
  }
  
  // Fill function (basic implementation)
  const fillArea = (e: React.MouseEvent<HTMLCanvasElement>) => {
    if (activeTool !== "fill") return
    
    const canvas = canvasRef.current
    if (!canvas) return
    
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    
    const rect = canvas.getBoundingClientRect()
    const x = Math.floor(e.clientX - rect.left)
    const y = Math.floor(e.clientY - rect.top)
    
    // Simple fill - in a real app, you'd use a flood fill algorithm
    ctx.fillStyle = activeColor
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    
    saveToHistory()
  }
  
  // Get cursor class based on active tool
  const getCursorClass = () => {
    switch (activeTool) {
      case "pencil":
        return "paint-cursor-pencil"
      case "eraser":
        return "paint-cursor-eraser"
      case "fill":
        return "paint-cursor-fill"
      case "text":
        return "paint-cursor-text"
      case "shape":
        return "paint-cursor-shape"
      case "select":
        return "paint-cursor-select"
      default:
        return ""
    }
  }
  
  return (
    <div className="relative w-full h-full overflow-hidden">
      <canvas
        ref={canvasRef}
        className={cn(
          "absolute top-0 left-0 w-full h-full bg-paint-canvas",
          getCursorClass(),
          className
        )}
        onMouseDown={activeTool === "fill" ? fillArea : startDrawing}
        onMouseMove={draw}
        onMouseUp={stopDrawing}
        onMouseLeave={stopDrawing}
      />
      
      {/* Text input for text tool */}
      {isTextInputActive && (
        <input
          ref={textInputRef}
          type="text"
          value={textInputValue}
          onChange={(e) => setTextInputValue(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              handleTextInputComplete()
            } else if (e.key === "Escape") {
              setIsTextInputActive(false)
              setTextInputValue("")
            }
          }}
          onBlur={handleTextInputComplete}
          style={{
            position: "absolute",
            left: `${textInputPosition.x}px`,
            top: `${textInputPosition.y}px`,
            color: activeColor,
            fontSize: `${brushSize * 2}px`,
            background: "transparent",
            border: "1px dashed #999",
            outline: "none",
            minWidth: "100px",
            padding: "2px",
            fontFamily: "Arial",
          }}
          autoFocus
        />
      )}
    </div>
  )
}